const pool: WechatMiniprogram.EVENT_POOL[] = []

const getItemByKey = (key: string) => pool.filter(k => k.key === key)
const getItemByUid = (uid: string) => pool.find(k => k.uid === uid)
const getItemIdxByUid = (uid: string) => pool?.findIndex(k => k.uid === uid)
const removeItem = (uid: string) => pool.splice(getItemIdxByUid(uid), 1);

wx.$events = {
  $hasListeners(key) {
    return getItemByKey(key).length > 0
  },
  $emit(key, ...args: any[]) {
    getItemByKey(key).forEach(item => {
      item.fn(...args);

      if (item.isOnce) removeItem(item.uid);
    })
  },
  $on(key, fn, isOnce) {
    pool.push({
      uid: `${pool.length}-${Math.random().toString().slice(2, 16)}`.padStart(18, 'x'),
      key: String(key),
      fn,
      isOnce
    })
  },
  $once: (...args) => wx.$events.$on(...args, true),
  $off(key) { getItemByKey(key).forEach(k => removeItem(k.uid)) },
}
